package com.fr.data.impl;

import com.fr.base.ArrayUtils;
import com.fr.base.FRContext;
import com.fr.data.TableDataException;
import com.fr.data.core.DataUtils;
import com.fr.data.core.db.ColumnInformation;
import com.fr.data.core.db.DBUtils;
import com.fr.data.core.db.dialect.Dialect;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.report.script.Primitive;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SpecialTreeDataAdapter extends TableDataAdapter
{
  private static final long serialVersionUID = -1391294406394533677L;
  private String[] markFields;
  private String[] parentmarkFields;
  private String[] treeField;
  private transient ColumnInformation[] columnInformations = null;
  private transient ColumnInformation[] realColumnInformations = null;
  private List databaseList;
  private List treedataList;
  private int addedFieldLength;
  private String defaultFieldName = "FR_GEN_";
  private int limitGeneration = -1;

  public SpecialTreeDataAdapter(DatabaseConnection paramDatabaseConnection, String paramString, String[] paramArrayOfString1, String[] paramArrayOfString2, String[] paramArrayOfString3, int paramInt)
  {
    super(paramDatabaseConnection, paramString, 0);
    setMarkFields(paramArrayOfString1);
    setParentmarkFields(paramArrayOfString2);
    setTreeField(paramArrayOfString3);
    this.limitGeneration = paramInt;
  }

  public String[] getMarkFields()
  {
    return this.markFields;
  }

  public void setMarkFields(String[] paramArrayOfString)
  {
    this.markFields = paramArrayOfString;
  }

  public String[] getParentmarkFields()
  {
    return this.parentmarkFields;
  }

  public void setParentmarkFields(String[] paramArrayOfString)
  {
    this.parentmarkFields = paramArrayOfString;
  }

  public String[] getTreeField()
  {
    return this.treeField;
  }

  public void setTreeField(String[] paramArrayOfString)
  {
    this.treeField = paramArrayOfString;
  }

  public String getDefaultFieldName()
  {
    return this.defaultFieldName;
  }

  public void setDefaultFieldName(String paramString)
  {
    this.defaultFieldName = paramString;
  }

  public int getRealColumnCount()
    throws TableDataException
  {
    checkRealColumn();
    return this.realColumnInformations.length;
  }

  public String getRealColumnName(int paramInt)
    throws TableDataException
  {
    checkRealColumn();
    return this.realColumnInformations[paramInt].getColumnName();
  }

  public int getAddedFieldLength()
  {
    return this.addedFieldLength;
  }

  public int getColumnCount()
    throws TableDataException
  {
    checkInColumn();
    return this.columnInformations.length;
  }

  public String getColumnName(int paramInt)
    throws TableDataException
  {
    checkInColumn();
    return this.columnInformations[paramInt].getColumnName();
  }

  private synchronized void initData()
    throws TableDataException
  {
    if (this.isCheckRowOver)
      return;
    initConnectionAndResultAndCheckInColumns();
    if ((this.databaseList.size() > 0) && (this.treedataList.size() > 0))
      return;
    if (this.connection == null)
      return;
    Dialect localDialect = DialectFactory.generateDialect(this.connection);
    int[] arrayOfInt1 = fields2Index(this.markFields);
    int[] arrayOfInt2 = fields2Index(this.parentmarkFields);
    int[] arrayOfInt3 = fields2Index(this.treeField);
    int i = getRealColumnCount();
    String str1 = this.database.getOriginalCharsetName();
    String str2 = this.database.getNewCharsetName();
    try
    {
      while (this.resultSet.next())
      {
        Object[] arrayOfObject = new Object[i];
        for (int j = 0; j < i; ++j)
          try
          {
            arrayOfObject[j] = DataUtils.getResultSetObject(this.resultSet, this.realColumnInformations[j].getColumnType(), j + 1, str1, str2, localDialect);
          }
          catch (SQLException localSQLException)
          {
            arrayOfObject[j] = null;
          }
        TreeAccessData localTreeAccessData = new TreeAccessData(getSelectedFields(arrayOfObject, arrayOfInt1), getSelectedFields(arrayOfObject, arrayOfInt2), arrayOfObject[arrayOfInt3[0]]);
        this.databaseList.add(arrayOfObject);
        this.treedataList.add(localTreeAccessData);
      }
      executeRelation(this.treedataList);
      this.isCheckRowOver = true;
      releaseConnection();
    }
    catch (Exception localException1)
    {
      try
      {
        releaseConnection();
      }
      catch (Exception localException2)
      {
        FRContext.getLogger().log(Level.WARNING, "Error happens while releaseConnection");
      }
      this.isCheckRowOver = true;
      throw new TableDataException(localException1.getMessage() + "initial treeTable Error!");
    }
  }

  private void executeRelation(List paramList)
  {
    int i = 0;
    int j = paramList.size();
    while (i < j)
    {
      TreeAccessData localTreeAccessData2;
      TreeAccessData localTreeAccessData1 = (TreeAccessData)paramList.get(i);
      if (checkNullArray(localTreeAccessData1.getParentmark()))
        break label108:
      Iterator localIterator = paramList.iterator();
      do
        while (true)
        {
          if (!(localIterator.hasNext()))
            break label108;
          localTreeAccessData2 = (TreeAccessData)localIterator.next();
          if (localTreeAccessData1 != localTreeAccessData2)
            break;
        }
      while (!(checkMark(localTreeAccessData2.getMark(), localTreeAccessData1.getParentmark())));
      localTreeAccessData1.setParentData(localTreeAccessData2);
      label108: ++i;
    }
    fireAddedFieldLength(paramList);
  }

  public boolean checkNullArray(String[] paramArrayOfString)
  {
    if (ArrayUtils.isEmpty(paramArrayOfString))
      return true;
    int i = 0;
    int j = paramArrayOfString.length;
    while (i < j)
    {
      if (paramArrayOfString[i] == null)
        return true;
      ++i;
    }
    return false;
  }

  public void fireAddedFieldLength(List paramList)
  {
    int i = 0;
    Iterator localIterator = paramList.iterator();
    while (true)
    {
      TreeAccessData localTreeAccessData;
      do
      {
        if (!(localIterator.hasNext()))
          break label47;
        localTreeAccessData = (TreeAccessData)localIterator.next();
      }
      while (i >= localTreeAccessData.extendLength());
      i = localTreeAccessData.extendLength();
    }
    label47: this.addedFieldLength = i;
  }

  public boolean checkMark(String[] paramArrayOfString1, String[] paramArrayOfString2)
  {
    if (paramArrayOfString1.length == paramArrayOfString2.length)
    {
      int i = 1;
      int j = 0;
      k = paramArrayOfString1.length;
      while (j < k)
      {
        if (paramArrayOfString1[j].equals(paramArrayOfString2[j]))
          break label45:
        i = 0;
        break;
        label45: ++j;
      }
      if (i == 0)
        break label151;
      return i;
    }
    StringBuffer localStringBuffer1 = new StringBuffer();
    StringBuffer localStringBuffer2 = new StringBuffer();
    int k = 0;
    int l = paramArrayOfString1.length;
    while (k < l)
    {
      localStringBuffer1 = localStringBuffer1.append(paramArrayOfString1[k]);
      ++k;
    }
    k = 0;
    l = paramArrayOfString2.length;
    while (k < l)
    {
      localStringBuffer2 = localStringBuffer2.append(paramArrayOfString2[k]);
      ++k;
    }
    label151: return (localStringBuffer1.toString().equals(localStringBuffer2.toString()));
  }

  public String[] getSelectedFields(Object[] paramArrayOfObject, int[] paramArrayOfInt)
  {
    String[] arrayOfString = new String[paramArrayOfInt.length];
    int i = 0;
    int j = paramArrayOfInt.length;
    while (i < j)
    {
      if ((paramArrayOfObject[paramArrayOfInt[i]] == null) || (paramArrayOfObject[paramArrayOfInt[i]].equals(Primitive.NULL)))
        arrayOfString[i] = null;
      else
        arrayOfString[i] = paramArrayOfObject[paramArrayOfInt[i]].toString();
      ++i;
    }
    return arrayOfString;
  }

  public int[] fields2Index(String[] paramArrayOfString)
    throws TableDataException
  {
    if (this.realColumnInformations == null)
      checkRealColumn();
    int[] arrayOfInt = new int[paramArrayOfString.length];
    int i = 0;
    int j = paramArrayOfString.length;
    while (i < j)
    {
      String str = paramArrayOfString[i];
      int k = 0;
      int l = this.realColumnInformations.length;
      while (k < l)
      {
        if (str.equals(this.realColumnInformations[k].getColumnName()))
        {
          arrayOfInt[i] = k;
          break;
        }
        ++k;
      }
      ++i;
    }
    return arrayOfInt;
  }

  public int getRowCount()
    throws TableDataException
  {
    hasRow(2147483647);
    return this.databaseList.size();
  }

  public Object getValueAt(int paramInt1, int paramInt2)
    throws TableDataException
  {
    if (hasRow(paramInt1))
    {
      if (paramInt2 < getRealColumnCount())
        return ((Object[])this.databaseList.get(paramInt1))[paramInt2];
      return ((TreeAccessData)this.treedataList.get(paramInt1)).getData(paramInt2 - getRealColumnCount());
    }
    return null;
  }

  protected boolean hasRow(int paramInt)
    throws TableDataException
  {
    initData();
    return (paramInt < this.databaseList.size());
  }

  protected void initRowValueStatus()
  {
    this.databaseList = new ArrayList();
    this.treedataList = new ArrayList();
  }

  private synchronized void checkRealColumn()
    throws TableDataException
  {
    if (this.realColumnInformations != null)
      return;
    Object[] arrayOfObject = { new String[0], new int[0], new String[0] };
    Connection localConnection = null;
    try
    {
      localConnection = this.database.createConnection();
      this.realColumnInformations = DBUtils.checkInColumnInformation(localConnection, this.sql, 0);
    }
    catch (Exception localException)
    {
      throw new TableDataException("Query: \"" + this.sql + "\"\n" + localException.getMessage(), localException);
    }
    finally
    {
      if (localConnection != null)
        try
        {
          localConnection.close();
        }
        catch (SQLException localSQLException)
        {
          FRContext.getLogger().log(Level.INFO, localSQLException.getMessage(), localSQLException);
        }
    }
  }

  protected synchronized void checkInColumn()
    throws TableDataException
  {
    if (this.columnInformations != null)
      return;
    if (this.realColumnInformations == null)
      checkRealColumn();
    int[] arrayOfInt = fields2Index(this.treeField);
    this.columnInformations = ((ColumnInformation[])ArrayUtils.addAll(this.realColumnInformations, createAddedField(arrayOfInt[0])));
  }

  private ColumnInformation[] createAddedField(int paramInt)
    throws TableDataException
  {
    if ((this.limitGeneration <= 0) && (this.addedFieldLength == 0))
      initData();
    int i = (this.limitGeneration > 0) ? this.limitGeneration : getAddedFieldLength();
    ColumnInformation[] arrayOfColumnInformation = new ColumnInformation[i];
    for (int j = 0; j < i; ++j)
      arrayOfColumnInformation[j] = new ColumnInformation(this.defaultFieldName + j, paramInt, this.defaultFieldName + j);
    return arrayOfColumnInformation;
  }

  protected synchronized void release()
    throws SQLException
  {
    if (this.databaseList != null)
      this.databaseList.clear();
    if (this.treedataList != null)
      this.treedataList.clear();
    this.isCheckRowOver = false;
    super.release();
  }
}